#include "SkeletonNode.h"
#include "Skeleton.h"
#include "boost/foreach.hpp"

SkeletonNode::SkeletonNode(tstring name,int id):m_Name(name),m_ID(id),m_Parent(NULL),m_pAnimation(NULL)
{
}

SkeletonNode::~SkeletonNode(void)
{
}

void SkeletonNode::Animate(Skeleton* skeleton, DAEMatrix& deltaTrans, float time)
{
	DAEMatrix worldTransform;
	if ( m_pAnimation != NULL ){
		
		m_pAnimation->GetTransformAt(time,deltaTrans,worldTransform);
		m_BoneInv.Multiply(&m_GlobalTrans,&worldTransform);

	}else{
		m_GlobalTrans.SetAsIdentity();
	}
	skeleton->SetBoneMatrix(m_ID,m_GlobalTrans);
	vector<SkeletonNode*>::const_iterator it;

	DAEMatrix delta;
	m_BoneInv.Multiply(&delta,&worldTransform);
	for (it = m_ChildNodes.begin();it!=m_ChildNodes.end();++it)
	{
		SkeletonNode* child =*it;
		child->Animate(skeleton, delta , time);
	}
}

SkeletonNode* SkeletonNode::Clone() const
{
	SkeletonNode* copy = new SkeletonNode(m_Name, m_ID);
	copy->m_InitialPose = this->m_InitialPose;
	copy->m_BoneInv = this->m_BoneInv;

	if ( copy->m_Parent )
		copy->m_Parent->AddNode(copy);
	return copy;
}

void SkeletonNode::SetTransform(float tx, float ty,float tz, float rx, float ry, float rz, float sx, float sy,float sz)
{
	m_InitialPose.SetTranslation(tx,ty,tz);
	m_InitialPose.SetRotation(rx,ry,rz);
	m_InitialPose.SetScale(sx,sy,sz);
	
	DAEMatrix transform = m_InitialPose.GetCompiledMatrix();
	transform.Inverse(m_BoneInv);
}

void SkeletonNode::SetRotation(float rx, float ry, float rz)
{
	m_InitialPose.SetRotation(rx,ry,rz);
	DAEMatrix transform = m_InitialPose.GetCompiledMatrix();
	transform.Inverse(m_BoneInv);
}

void SkeletonNode::GetRotation(DAEFloat3& rotation)
{
	rotation.x = m_InitialPose.GetRotX();
	rotation.y = m_InitialPose.GetRotY();
	rotation.z = m_InitialPose.GetRotZ();
}

void SkeletonNode::GetTranslation(DAEFloat3& translation)
{
	translation.x = m_InitialPose.GetTransX();
	translation.y = m_InitialPose.GetTransY();
	translation.z = m_InitialPose.GetTransZ();
}

void SkeletonNode::GetScale(DAEFloat3& scale)
{
	scale.x = m_InitialPose.GetScaleX();
	scale.y = m_InitialPose.GetScaleY();
	scale.z = m_InitialPose.GetScaleZ();
}

